#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.basic.security.imagecode;

import ${package}.common.bean.vo.JsonResult;
import ${package}.common.component.service.RedisService;
import ${package}.common.emum.ReturnCodeEnum;
import ${package}.common.utils.UUIDUtil;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * Description:
 *
 * @author Zhoumaofa
 * @date 2020/2/7 14:30
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
@RestController
@AllArgsConstructor
@Slf4j
public class ValidateCodeController {

	private RedisService redisService;


	/**
	 * Description:
	 * <创建验证码>
	 *
	 * @return void
	 * @author Zhoumaofa
	 * @date 11:32 2020/2/10
	 **/
	@GetMapping("/code/getCode")
	public JsonResult createCode() throws IOException, NoSuchAlgorithmException {
		ImageCode imageCode = createImageCode();
		String token = UUIDUtil.get32UUID();
		redisService.set(token, JSON.toJSONString(imageCode), 300L);

		Map<String, String> code = new HashMap<>(2);
		code.put("token", token);
		code.put("image", imageCode.getImage());
		return JsonResult.getInstant(ReturnCodeEnum.SUCCESS, code);
	}

	/**
	 * Description:
	 * <判断是否需要请求验证码>
	 *
	 * @param username 1
	 * @return ${package}.common.bean.vo.JsonResult<java.lang.String>
	 * @author Zhoumaofa
	 * @date 14:45 2020/3/7
	 **/
	@GetMapping("/code/getNum")
	public JsonResult<String> getNum(String username) {
		//状态为0的时候不需要请求验证码，状态为1的时候需要请求验证码
		String status = "0";
		//设置过期时间为12小时
		Long expireTime = 60 * 5L;
		Object userName = redisService.get(username);
		if (userName == null) {
			redisService.set(username, status, expireTime);
			userName = redisService.get(username);
		}
		return JsonResult.getInstant(ReturnCodeEnum.SUCCESS, userName.toString());
	}

	/**
	 * Description:
	 * <创建验证码>
	 *
	 * @return ${package}.basic.security.imagecode.ImageCode
	 * @author Zhoumaofa
	 * @date 15:21 2020/2/14
	 **/
	private ImageCode createImageCode() throws IOException, NoSuchAlgorithmException {
		SecureRandom random = new SecureRandom();
		int width = 67;
		int height = 23;
		int randomNumber = 155;
		int codeDigit = 4;
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();
		g.setColor(getRandColor(200, 250));
		g.fillRect(0, 0, width, height);
		g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < randomNumber; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(12);
			int yl = random.nextInt(12);
			g.drawLine(x, y, x + xl, y + yl);
		}
		StringBuilder sRand = new StringBuilder();
		for (int i = 0; i < codeDigit; i++) {
			String rand = String.valueOf(random.nextInt(10));
			sRand.append(rand);
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			g.drawString(rand, 13 * i + 6, 16);
		}
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ImageIO.write(image, "PNG", os);
		String base64Image = "data:image/png;base64," + Base64.getEncoder().encodeToString(os.toByteArray());
		ImageCode imageCode = new ImageCode(base64Image, sRand.toString(), 60 * 60);
		return imageCode;
	}

	/**
	 * Description:
	 * <生成随机条纹背景>
	 *
	 * @param fc 1
	 * @param bc 2
	 * @return java.awt.Color
	 * @author Zhoumaofa
	 * @date 16:40 2020/2/7
	 **/
	private Color getRandColor(int fc, int bc) {
		SecureRandom random = new SecureRandom();
		int colorMax = 255;
		if (fc > colorMax) {
			fc = 255;
		}
		if (bc > colorMax) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

}
